/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cx1.dao.impl;

import com.ibatis.sqlmap.client.SqlMapClient;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.cx1.dao.api.IListingDao;
import org.cx1.model.Amenity;
import org.cx1.model.FurnishType;
import org.cx1.model.Listing;
import org.cx1.model.Photo;
import org.cx1.model.Place;
import org.cx1.model.PropertyType;
import org.cx1.model.utils.KFurnishTypeIDs;
import org.cx1.model.utils.KPropertyTypeIDs;
import org.cx1.model.utils.RateUtils;
import org.cx1.model.utils.SearchOption;

/**
 *
 * @author tina
 */
public class ListingDao implements IListingDao {
    
    private SqlMapClient sqlMapClient;

    public ListingDao() {
        sqlMapClient = IbatisConnectionFactory.getSqlMapClient();
    }
            
    public int countFiltered(SearchOption searchOption) {
        
        Map<String, Object> map = new HashMap<String, Object>();
        
        int offset = 0;
        int limit = 12;
       
        if (searchOption.getPage() == 1) {
            limit = searchOption.getPage() * searchOption.getItemsPerPage();
            offset = 0;
        }
        else {
            limit = searchOption.getItemsPerPage();
            offset = (searchOption.getPage() * searchOption.getItemsPerPage()) - (searchOption.getItemsPerPage());            
        }
       
        List<String> placeIDs = new ArrayList<String>();
        if (searchOption.getPlaces() != null && searchOption.getPlaces().size() > 0) {
            for (Place place : searchOption.getPlaces()) {
                placeIDs.add(place.getId());
            }
        }
                
        List<String> furnishTypeIDs = new ArrayList<String>();
        if (searchOption.getFurnishTypes() != null && searchOption.getFurnishTypes().size() > 0) {
            for (FurnishType furnishType : searchOption.getFurnishTypes()) {
                furnishTypeIDs.add(furnishType.getId());
            }
        }
        else {
            furnishTypeIDs.add(KFurnishTypeIDs.FULLY_FURNISHED);
            furnishTypeIDs.add(KFurnishTypeIDs.SEMI_FURNISHED);
            furnishTypeIDs.add(KFurnishTypeIDs.UNFURNISHED);
        }
        
        List<String> propertyTypeIDs = new ArrayList<String>();
        //propertyTypeIDs.add("1");
        if (searchOption.getPropertyTypes() != null && searchOption.getPropertyTypes().size() > 0) {
            for (PropertyType propertyType : searchOption.getPropertyTypes()) {
                propertyTypeIDs.add(propertyType.getId());
            }
        }
        else {
            propertyTypeIDs.add(KPropertyTypeIDs.APARTMENT);
            propertyTypeIDs.add(KPropertyTypeIDs.CONDOMINIUM);
            propertyTypeIDs.add(KPropertyTypeIDs.HOUSE);
            propertyTypeIDs.add(KPropertyTypeIDs.TOWNHOUSE);
            propertyTypeIDs.add(KPropertyTypeIDs.ROOM);
        }
        
        map.put("limit", limit);
        map.put("offset", offset);
        
        map.put("placeIDs", placeIDs);
        map.put("furnishTypeIDs", furnishTypeIDs);
        map.put("propertyTypeIDs", propertyTypeIDs);        
        
        map.put("longMonthRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getLongMonthRateLow()));
        map.put("longMonthRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getLongMonthRateHigh()));
        map.put("shortMonthRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortMonthRateLow()));
        map.put("shortMonthRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortMonthRateHigh()));
        map.put("shortWeekRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortWeekRateLow()));
        map.put("shortWeekRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortWeekRateHigh()));
        map.put("shortDayRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortDayRateLow()));
        map.put("shortDayRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortDayRateHigh()));
        
        map.put("numBedroomsHigh", searchOption.getListingFilter().getNumBedroomsHigh());
        map.put("numBedroomsLow", searchOption.getListingFilter().getNumBedroomsLow());
        map.put("numBathroomsHigh", searchOption.getListingFilter().getNumBathroomsHigh());
        map.put("numBathroomsLow", searchOption.getListingFilter().getNumBathroomsLow());
        map.put("leaseLongTerm", searchOption.getLeaseTerm() == 1 ? 1 : 0);
        map.put("leaseShortTerm", searchOption.getLeaseTerm() == 2 ? 1 : 0);
        map.put("posted", true);
        
        String strCount = "0";
        int count = 0;
        try {
            strCount = (String) sqlMapClient.queryForObject("listing.countFiltered", map);
            count = Integer.parseInt(strCount);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return count;
    }
    
    
    @Override
    public List<Listing> getFiltered(SearchOption searchOption) {
        
        Map<String, Object> map = new HashMap<String, Object>();
        
        int offset = 0;
        int limit = 12;
       
        if (searchOption.getPage() == 1) {
            limit = searchOption.getPage() * searchOption.getItemsPerPage();
            offset = 0;
        }
        else {
            limit = searchOption.getItemsPerPage();
            offset = (searchOption.getPage() * searchOption.getItemsPerPage()) - (searchOption.getItemsPerPage());            
        }
       
        List<String> placeIDs = new ArrayList<String>();
        if (searchOption.getPlaces() != null && searchOption.getPlaces().size() > 0) {
            for (Place place : searchOption.getPlaces()) {
                placeIDs.add(place.getId());
            }
        }
                
        List<String> furnishTypeIDs = new ArrayList<String>();
        if (searchOption.getFurnishTypes() != null && searchOption.getFurnishTypes().size() > 0) {
            for (FurnishType furnishType : searchOption.getFurnishTypes()) {
                furnishTypeIDs.add(furnishType.getId());
            }
        }
        else {
            furnishTypeIDs.add(KFurnishTypeIDs.FULLY_FURNISHED);
            furnishTypeIDs.add(KFurnishTypeIDs.SEMI_FURNISHED);
            furnishTypeIDs.add(KFurnishTypeIDs.UNFURNISHED);
        }
        
        List<String> propertyTypeIDs = new ArrayList<String>();
        propertyTypeIDs.add("1");
        if (searchOption.getPropertyTypes() != null && searchOption.getPropertyTypes().size() > 0) {
            for (PropertyType propertyType : searchOption.getPropertyTypes()) {
                propertyTypeIDs.add(propertyType.getId());
            }
        }
        else {
            propertyTypeIDs.add(KPropertyTypeIDs.APARTMENT);
            propertyTypeIDs.add(KPropertyTypeIDs.CONDOMINIUM);
            propertyTypeIDs.add(KPropertyTypeIDs.HOUSE);
            propertyTypeIDs.add(KPropertyTypeIDs.TOWNHOUSE);
            propertyTypeIDs.add(KPropertyTypeIDs.ROOM);
        }
        
        map.put("limit", limit);
        map.put("offset", offset);
        
        map.put("placeIDs", placeIDs);
        map.put("furnishTypeIDs", furnishTypeIDs);
        map.put("propertyTypeIDs", propertyTypeIDs);
        
        map.put("longMonthRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getLongMonthRateLow()));
        map.put("longMonthRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getLongMonthRateHigh()));
        map.put("shortMonthRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortMonthRateLow()));
        map.put("shortMonthRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortMonthRateHigh()));
        map.put("shortWeekRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortWeekRateLow()));
        map.put("shortWeekRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortWeekRateHigh()));
        map.put("shortDayRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortDayRateLow()));
        map.put("shortDayRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortDayRateHigh()));
        map.put("numBedroomsHigh", searchOption.getListingFilter().getNumBedroomsHigh());
        map.put("numBedroomsLow", searchOption.getListingFilter().getNumBedroomsLow());
        map.put("numBathroomsHigh", searchOption.getListingFilter().getNumBathroomsHigh());
        map.put("numBathroomsLow", searchOption.getListingFilter().getNumBathroomsLow());
        map.put("leaseLongTerm", searchOption.getLeaseTerm() == 1 ? 1 : 0);
        map.put("leaseShortTerm", searchOption.getLeaseTerm() == 2 ? 1 : 0);
        map.put("posted", true);
        
        List<Listing> listings = new ArrayList<Listing>();
        try {
            listings = sqlMapClient.queryForList("listing.getFiltered", map);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return listings;
    }
    
    
    @Override
    public List<Listing> getFilteredVerified(SearchOption searchOption) {
        
        Map<String, Object> map = new HashMap<String, Object>();
        
        int offset = 0;
        int limit = 12;
       
        if (searchOption.getPage() == 1) {
            limit = searchOption.getPage() * searchOption.getItemsPerPage();
            offset = 0;
        }
        else {
            limit = searchOption.getItemsPerPage();
            offset = (searchOption.getPage() * searchOption.getItemsPerPage()) - (searchOption.getItemsPerPage());            
        }
       
        List<String> placeIDs = new ArrayList<String>();
        if (searchOption.getPlaces() != null && searchOption.getPlaces().size() > 0) {
            for (Place place : searchOption.getPlaces()) {
                placeIDs.add(place.getId());
            }
        }
                
        List<String> furnishTypeIDs = new ArrayList<String>();
        if (searchOption.getFurnishTypes() != null && searchOption.getFurnishTypes().size() > 0) {
            for (FurnishType furnishType : searchOption.getFurnishTypes()) {
                furnishTypeIDs.add(furnishType.getId());
            }
        }
        else {
            furnishTypeIDs.add(KFurnishTypeIDs.FULLY_FURNISHED);
            furnishTypeIDs.add(KFurnishTypeIDs.SEMI_FURNISHED);
            furnishTypeIDs.add(KFurnishTypeIDs.UNFURNISHED);
        }
        
        List<String> propertyTypeIDs = new ArrayList<String>();
        //propertyTypeIDs.add("1");
        if (searchOption.getPropertyTypes() != null && searchOption.getPropertyTypes().size() > 0) {
            for (PropertyType propertyType : searchOption.getPropertyTypes()) {
                propertyTypeIDs.add(propertyType.getId());
            }
        }
        else {
            propertyTypeIDs.add(KPropertyTypeIDs.APARTMENT);
            propertyTypeIDs.add(KPropertyTypeIDs.CONDOMINIUM);
            propertyTypeIDs.add(KPropertyTypeIDs.HOUSE);
            propertyTypeIDs.add(KPropertyTypeIDs.TOWNHOUSE);
            propertyTypeIDs.add(KPropertyTypeIDs.ROOM);
        }
        
        map.put("limit", limit);
        map.put("offset", offset);
        
        map.put("placeIDs", placeIDs);
        map.put("furnishTypeIDs", furnishTypeIDs);
        map.put("propertyTypeIDs", propertyTypeIDs);
        
        map.put("longMonthRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getLongMonthRateLow()));
        map.put("longMonthRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getLongMonthRateHigh()));
        map.put("shortMonthRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortMonthRateLow()));
        map.put("shortMonthRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortMonthRateHigh()));
        map.put("shortWeekRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortWeekRateLow()));
        map.put("shortWeekRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortWeekRateHigh()));
        map.put("shortDayRateLow", RateUtils.strRateToNum(searchOption.getListingFilter().getShortDayRateLow()));
        map.put("shortDayRateHigh", RateUtils.strRateToNum(searchOption.getListingFilter().getShortDayRateHigh()));
        map.put("numBedroomsHigh", searchOption.getListingFilter().getNumBedroomsHigh());
        map.put("numBedroomsLow", searchOption.getListingFilter().getNumBedroomsLow());
        map.put("numBathroomsHigh", searchOption.getListingFilter().getNumBathroomsHigh());
        map.put("numBathroomsLow", searchOption.getListingFilter().getNumBathroomsLow());
        map.put("leaseLongTerm", searchOption.getLeaseTerm() == 1 ? 1 : 0);
        map.put("leaseShortTerm", searchOption.getLeaseTerm() == 2 ? 1 : 0);
        map.put("posted", true);
        
        List<Listing> listings = new ArrayList<Listing>();
        try {
            listings = sqlMapClient.queryForList("listing.getFilteredVerified", map);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return listings;
    }
    
    @Override
    public List<Listing> getAll() {
        List<Listing> listings = new ArrayList<Listing>();
        
        try {
            listings = sqlMapClient.queryForList("listing.getAll");
        } catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return listings;
    }
        
    @Override
    public Listing getById(String id) {
        Listing listing = null;
        
        try {
            listing = (Listing) sqlMapClient.queryForObject("listing.getById", id);
        } catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return listing;
    }
    
    @Override
    public String add(Listing listing) {
        String listingId = "";
        
        try {
            sqlMapClient.insert("listing.add", listing);
            listingId = listing.getId();
            
        } catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return listingId;
    }

    @Override
    public int update(Listing listing) {
        int noOfRowsAffected = 0;
        
        try {
            noOfRowsAffected = sqlMapClient.update("listing.update", listing);
        } catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return noOfRowsAffected;
    }

    @Override
    public int deleteById(String id) {
        int noOfRowsAffected = 0;
        
        try {
            noOfRowsAffected = sqlMapClient.delete("listing.deleteById", id);
        } catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return noOfRowsAffected;
    }

    @Override
    public List<String> getAllAmenityRefIDs(String listingID) {
        List<String> placeRefIDs = new ArrayList<String>();
        try {
            Map<String,String> map = new HashMap<String, String>();
            map.put("listingID", listingID);
            placeRefIDs = (ArrayList<String>)sqlMapClient.queryForList("listing.getAllAmenityRefIDs", map);            
        } 
        catch (SQLException ex) {
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return placeRefIDs;
    }

    @Override
    public String addAmenityRef(String listingID, String amenityID) {
        String placeId = "";        
        try {
            Map<String,String> map = new HashMap<String, String>();
            map.put("listingID", listingID);
            map.put("amenityID", amenityID);        
            sqlMapClient.insert("listing.addAmenityRef", map);   
        } 
        catch (SQLException ex) {
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return placeId;
    }

    @Override
    public int deleteAllAmenityRef(String listingID) {
        int noOfRowsAffected = 0;        
        Map<String,String> map = new HashMap<String, String>();
        map.put("listingID", listingID);        
        try {
            noOfRowsAffected = sqlMapClient.delete("listing.deleteAllAmenityRef", map);
        } 
        catch (SQLException ex) {
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return noOfRowsAffected;
    }

    @Override
    public List<String> getAllPlaceRefIDs(String listingID) {
        List<String> placeRefIDs = new ArrayList<String>();
        try {
            Map<String,String> map = new HashMap<String, String>();
            map.put("listingID", listingID);
            placeRefIDs = (ArrayList<String>)sqlMapClient.queryForList("listing.getAllPlaceRefIDs", map);            
        } 
        catch (SQLException ex) {
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return placeRefIDs;
    }

    @Override
    public String addPlaceRef(String listingID, String placeID, String placeTypeID) {
        String placeId = "";        
        try {
            Map<String,String> map = new HashMap<String, String>();
            map.put("listingID", listingID);
            map.put("placeID", placeID);      
            map.put("placeTypeID", placeTypeID);        
            sqlMapClient.insert("listing.addPlaceRef", map);   
        } 
        catch (SQLException ex) {
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, "listingID- " + listingID + " placeID- " + placeID + " placeTypeID- " + placeTypeID);
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return placeId;
    }

    @Override
    public int deleteAllPlaceRef(String listingID) {
        int noOfRowsAffected = 0;        
        Map<String,String> map = new HashMap<String, String>();
        map.put("listingID", listingID);        
        try {
            noOfRowsAffected = sqlMapClient.delete("listing.deleteAllPlaceRef", map);
        } 
        catch (SQLException ex) {
            Logger.getLogger(PlaceDao.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return noOfRowsAffected;
    }

    @Override
    public int incrementImpressions(String listingID) {   
        int noOfRowsAffected = 0;     
        Map<String,String> map = new HashMap<String, String>();
        map.put("listingID", listingID);        
        
        try {
            noOfRowsAffected = sqlMapClient.update("listing.incrementImpressions", map);
        } 
        catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return noOfRowsAffected;
    }

    @Override
    public int incrementViews(String listingID) {        
        int noOfRowsAffected = 0;     
        Map<String,String> map = new HashMap<String, String>();
        map.put("listingID", listingID);        
        
        try {
            noOfRowsAffected = sqlMapClient.update("listing.incrementViews", map);
        } 
        catch (SQLException ex) {
            Logger.getLogger(ListingDao.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return noOfRowsAffected;
    }
    
    
    public static void main(String[] argv) {
        IListingDao listingDao = new ListingDao();
        
        
        listingDao.incrementImpressions("ab1d2a9b74");
        listingDao.incrementViews("ab1d2a9b74");
    }

}
